#include "mboard.h"
#include "mboard_private.h"
#include "tim_base_hw.h"
#include "rcc.h"
#include "nvic.h"
#include "mdebug.h"

/**
 * TIM6配置10ms单脉冲中断，用于按键消抖
 */

static void mTimBaseClockInit(void)
{
	/* 使能TIM6时钟 */
	RCC_EnableApb1(RCC_CLK_APB1_TIM6);
}

static void mTimBaseDeviceInit(void)
{
	/* mboardInfo.clk.apb1_tim = 84000000，分频到2000，0.5ms */
	SOC_TIM6.PSC = TIM_BASE_PSC_1_65536D(mboardInfo.clk.apb1_tim/2000);
	/* 0.5ms*20=10ms，设置为1的时候定时器不计数 */
	SOC_TIM6.ARR = TIM_BASE_ARR_1_65536D(20);
	/* 使能更新事件中断，禁止DMA触发 */
	SOC_TIM6.DIER = TIM_BASE_DIER_UIE_EN | TIM_BASE_DIER_UDE_DIS;
	/* 禁用影子模式、单脉冲、仅响应溢出事件，停止计数 */
	SOC_TIM6.CR1= TIM_BASE_CR1_DIS | TIM_BASE_CR1_UEV_OVER |
	              TIM_BASE_CR1_OPM_EN | TIM_BASE_CR1_ARPE_DIS;
	/* 初始化定时器，不初始化的话定时器第一个周期有点问题，不清楚为什么。
	   CR1默认值使能了UG事件，所以如果EGR在CR1前面配置会置起SR，同时NVIC
	   中的PEND位会置起，虽然此时NVIC中的中断并未使能 */
	SOC_TIM6.EGR = TIM_BASE_EGR_UG_EN;
}

static void mTimBaseInterrupt(void)
{
	NVIC_SetPriority(NVIC_IRQ_TIM6_DAC, NVIC_PRIORITY_LOW,
	                 NVIC_PRIORITY_SUB_NONE);
	NVIC_EnableIrq(NVIC_IRQ_TIM6_DAC);
}

void mTimBaseInit(void)
{
	mTimBaseClockInit();
	mTimBaseDeviceInit();
	mTimBaseInterrupt();
}

void mTimBaseTest(void)
{
	uint32_t start;
	uint32_t end;

	while (1) {
		start = mboardInfo.ms;
		/* 使能定时器 */
		SOC_TIM6.CR1 |= TIM_BASE_CR1_EN;
		/* 等待定时器终止 */
		while (SOC_TIM6.CR1 & TIM_BASE_CR1_EN);
		end = mboardInfo.ms;
		mDebugPrintf("10ms pulse: %u %u %ums\n", start, end, end-start);
		mBoardDelayMs(500);
	}
}
